#!/usr/bin/perl -w

BEGIN {
	if(exists($ENV{TRUECL_LIBS})) {
		push @INC,$ENV{TRUECL_LIBS};
	}
	if(exists($ENV{TRUECL_CODE})) {
		push @INC,"$ENV{TRUECL_CODE}/lib";
	}
}

use strict;
use cldb;
use Getopt::Long;
use File::Basename;

$::_PRG=basename($0);

%::records=(
	);

%::tables=(
	"known_net_connections" =>
		"CREATE TABLE known_net_connections(
			ipaddr	VARCHAR(50) PRIMARY KEY,
			timeout	VARCHAR(6),
			attributes VARCHAR(200)
		);",
	"storage_raw" =>
		"CREATE TABLE storage_raw(
			appname VARCHAR(50),
			logical VARCHAR(50),
			physical VARCHAR(255)
		);",
	"globals"	=>
		"CREATE TABLE globals(
			var VARCHAR(50) PRIMARY KEY,
			value VARCHAR(200)
		);",
	"custom_app_probes" =>
		"CREATE TABLE custom_app_probes(
			name VARCHAR(50) PRIMARY KEY,
			script VARCHAR(2048),
			update_time INTEGER
		);",
	"ports"	=> 
		"CREATE TABLE ports(
			number INTEGER PRIMARY KEY,
			type VARCHAR(10),
			detail VARCHAR(30)
		);",
	"nodes" => 
		"CREATE TABLE nodes(
			name VARCHAR(50) PRIMARY KEY,
			release VARCHAR(20),
			lha_release VARCHAR(20),
			ips VARCHAR(50),
			netmasks VARCHAR(100)
		);",
	"application_routes" => 
		"CREATE TABLE application_routes(
			label VARCHAR(50),
			appname VARCHAR(50),
			ipaddr VARCHAR(30),
			iptype INTEGER,
			timeout CHAR(6),
			maxfails INTEGER,
			resettime INTEGER,
			severity CHAR(10),
			comments CHAR(80)
		);",
	"topology" => 
		"CREATE TABLE topology(
			name VARCHAR(50) PRIMARY KEY,
			lcards VARCHAR(200),
			pcards VARCHAR(200),
			type VARCHAR(200),
			attributes VARCHAR(200)
		);",
	"applications" => 
		"CREATE TABLE applications(
			name		VARCHAR(50),
			prefnode	VARCHAR(20),
			nodes		VHARCHAR(255),
			consistency	VARCHAR(10),
			startscript	VARCHAR(255),
			stopscript	VARCHAR(255),
			lmigrate	CHAR(1),
			migratescript	CARCHAR(255),
			migratetimeout	INTEGER,
			migratetransport VARCHAR(20),
			vmtype		VARCHAR(20),
			starttimeout	INTEGER,
			stoptimeout	INTEGER,
			storage		VARCHAR(40),
			vgs		VARCHAR(255),
			changetime      INTEGER,
			validated	CHAR(1)
		);",
	"cluster_events" =>
		"CREATE TABLE cluster_events(
			name		VARCHAR(30) PRIMARY KEY,
			event		VARCHAR(20),
			text		VARCHAR(80),
			type		CHAR(10),
			send_host	VARCHAR(30),
			send_port	INTEGER,
			send_email	VARCHAR(255),
			send_file	VARCHAR(255),
			send_cmd	VARCHAR(255)
		);",
	"application_ips" =>
		"CREATE TABLE application_ips(
			name		VARCHAR(50),
			network		VARCHAR(50),
			ips		VARCHAR(200),
			netmask		VARCHAR(30),
			broadcast	VARCHAR(30),
			version		INTEGER,
			topology	VARCHAR(50)
		);",
	"application_fs" =>
		"CREATE TABLE application_fs(
			name		VARCHAR(50),
			mountpnt	VARCHAR(255),
			options		VARCHAR(50),
			fstype		VARCHAR(10),
			vg		VARCHAR(30),
			lv		VARCHAR(30),
			size		INTEGER
		);",
	"locks" =>
		"CREATE TABLE locks(
			name		VARCHAR(20),
			type		VARCHAR(20),
			desc		VARCHAR(200),
			maxtime		INTEGER,
			maxkeepers	INTEGER
		);",
	"storage_shared" =>
		"CREATE TABLE storage_shared(
			name		VARCHAR(50),
			vglv		VARCHAR(50),
			vischeck	VARCHAR(200)
		);",
	"storage_nfs" => 
		"CREATE TABLE storage_nfs(
			name		VARCHAR(50),
			vglv 		VARCHAR(50),
			vischeck 	VARCHAR(200)
		);",
	"event_monitor" =>
		"CREATE TABLE event_monitor(
			type		CHAR(1),
			name		VARCHAR(20),
			appname		VARCHAR(20),
			xml		VARCHAR(2048),
			update_time	INTEGER
		);",
	"storage_drbd1" =>
		"CREATE TABLE storage_drbd1(
			devnum		INTEGER,
			appname		VARCHAR(50),
			devport		VARCHAR(20),
			vglv		VARCHAR(50),
			topology	VARCHAR(50),
			syncrate	INTEGER,
			vischeck	VARCHAR(200),
			synched		CHAR(1),
			validhost	VARCHAR(20)
		);",
	"storage_drbd8" =>
		"CREATE TABLE storage_drbd8(
			devnum		INTEGER,
			appname		VARCHAR(50),
			devport		VARCHAR(20),
			vglv		VARCHAR(50),
			topology	VARCHAR(50),
			vischeck	VARCHAR(200),
			syncrate	INTEGER,
			auth_crc	VARCHAR(20),
			data_crc	VARCHAR(20),
			synched		CHAR(1),
			validhost	VARCHAR(20)
		);",
	"diskhb" =>
		"CREATE TABLE diskhb(
			hbkey		VARCHAR(50),
			name		VARCHAR(30),
			node		VARCHAR(50),
			devpath		VARCHAR(100),
			blksize		INTEGER,
			read_offset	INTEGER,
			write_offset	INTEGER,
			update_time	INTEGER,
			validated	INTEGER
		);",
);


sub usage {
	print "
Usage: $::_PRG [--dbfile S] [--force]

The $::_PRG utility is used to create an initial configuration
database file for linuxha.net v2. At present it supports the 
following arguments:

--dbfile	The name of the database file to create - it
		must be specified or the command will abort.
--force         Allowed to run when the database exists and
                will only create tables that do not currently
		exist.

Currently it will generate the following tables:

";
	print "  * $_\n" for (sort(keys %::tables));
	print "\n";
	exit 1;
}

$::ARG_dbfile=undef;
$::ARG_force=0;

if(!GetOptions(
	"dbfile=s"	=> \$::ARG_dbfile,
	"force"		=> \$::ARG_force,
)) {
	usage;
}

if(!defined($::ARG_dbfile)) {
	usage;
}

if(-f $::ARG_dbfile && ! $::ARG_force) {
	print STDERR "Error: File $::ARG_dbfile already exists - not overwriting.\n";
	exit 1;
}

$::DBH = new cldb($::ARG_dbfile);
if(!defined($::DBH)) {
	($::rc,$::str)=cldb::error;
	print STDERR "Error: $::str [rc=$::rc]\n";
	exit 1;
}

for $::table (sort(keys %::tables)) {
	$::DBH->do($::tables{$::table});
	($::cc,$::rc)=$::DBH->error;
	if(defined($::rc)) {
		if($::rc =~ /already exists/) {
			print "Log  : Table \"$::table\" already exists.\n";
		} else {
			print STDERR "Error: Failed to create table $::table - $::rc:\n";
		}
	} else {
		print "Log  : Table \"$::table\" created successfully.\n";
	}
}

#########################################################################
# Once the tables have been created add any necessary base records.	#
#########################################################################

for $::rectype (sort(keys(%::records))) {
	for $::crec (@{$::records{$::rectype}}) {
		$::cmd="INSERT INTO $::rectype VALUES(";
		$::cmd.="'$_'," foreach(@$::crec);
		$::cmd =~ s/,$//;
		$::cmd.=");";
		$::DBH->do($::cmd);
		($::cc,$::rc)=$::DBH->error;
		if(defined($::rc)) {
			print "Error: Unable to insert record into $::rectype:\n";
			print "Error: $::rc\n";
			exit 1;
		}
	}
}

$::DBH->disconnect;
$::DBH->force_close;

exit;
